﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using MVCnExt.Util;
using MVCnExt.Web.UI.Ext;
using System.Web.Script.Serialization;
using System.Reflection;

namespace MVCnExt.Controllers
{
    [HandleError]
    public class TreeController : Controller
    {
        public ActionResult Manual()
        {
            ViewData["Title"] = "Example of Manual Tree";

            return View();
        }
       
        public ActionResult Loader()
        {
            ViewData["Title"] = "Example of Manual Tree";

            return View();
        }

        public ActionResult Editor()
        {
            ViewData["Title"] = "Example of Tree Editor";

            return View();
        }

        public ActionResult Sorter()
        {
            ViewData["Title"] = "Example of Tree Editor";

            return View();
        }

        public TreeLoader List()
        {
            ViewData["Title"] = "Example of Tree Loader";

            List<ExtTreeNode> children = new List<ExtTreeNode>()
            {
                new ExtTreeNode() { leaf= true, text="text1" }
            };

            List<ExtTreeNode> root = new List<ExtTreeNode>()
            {
                new ExtTreeNode() { leaf= true, text="text1" },
                new ExtTreeNode() { text="text1", children = children }
            };

            return new TreeLoader(root);
        }
    }

    public class TreeLoader : JsonResult
    {
        public TreeLoader(object loaderData)
        {
            Data = loaderData;
        }

        public override void ExecuteResult(ControllerContext context)
        {
            if (context == null)
                throw new ArgumentNullException("context");

            var response = context.HttpContext.Response;

            if (Data != null)
            {
                var serializer = new JavaScriptSerializer();
                List<JavaScriptConverter> converters = new List<JavaScriptConverter>();
                converters.Add(new TreeLoaderConvertor());
                serializer.RegisterConverters(converters);
                response.Write(serializer.Serialize(Data));
            }
        }
    }

    internal class TreeLoaderConvertor : JavaScriptConverter
    {
        Dictionary<string, object> desc = new Dictionary<string, object>();
        ExtTreeNode node;

        public override IEnumerable<Type> SupportedTypes
        {
            get { return new Type[] { typeof(ExtTreeNode) }; }
        }

        public override object Deserialize(IDictionary<string, object> dictionary, Type type,
                                           JavaScriptSerializer serializer)
        {
            throw new NotImplementedException();
        }

        public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
        {
            node = obj as ExtTreeNode;            

            if (node != null)
            {                
                desc = new Dictionary<string, object>();

                Type component = typeof(ExtTreeNode);

                var propertyList = from property in component.GetProperties()
                                   where property.DeclaringType == component
                                   select property;

                propertyList.ToList().ForEach(AddProperty);
            }

            return desc;
        }

        public virtual void AddProperty(PropertyInfo property)
        {
            if (property == null)
                throw new InvalidOperationException(String.Format("Property not found, 'ExtJsComponent.{0}'", property));

            Object value = property.GetValue(node, null);

            if (value == null)
                return;

            desc.Add(property.Name, value);
        }
    }

}
